/*
** Copyright (c) K-Marrade
** All rights reserved.
**
** idt.c : idt stuff.
**
** Use with caution.
**
*/

#include "kstd.h"
#include "stdio.h"
#include "idt.h"
#include "pic.h"
#include "keyboard.h"
#include "asm_wrapper.h"
#include "timer.h"

static t_interrupt_gate idt[256];

void generic_handler(t_uint32 num)
{
  switch (num)
    {

    case 0:
      printf("Divide Error Exception\n");
      break;

    case 64:
      outb(0x20, 0x20);
      inctick();
      break;

    case 65:
      keyboard_event();
      break;

    default:
      printf("Unhandled interruption %u.\n", num);
      break;
    }

  if (num <= 13)
    while (1);
}

void idt_init(void)
{
  t_idtr idtr;

  idt_clear();

  idtr.limit = sizeof(idt) - 1;
  idtr.idt = (t_uint32) &idt;

  __asm__ ("lidt %0"
	   : /* Outputs */
	   : "m" (idtr) /* Inputs */
	   : /* Clobber registers */);

  asm volatile ("cli");
}

void idt_clear(void)
{
  int i;
  /* t_interrupt_gate generic_gate; */

  for (i = 0; i < 256; ++i)
    {
      idt[i].offset = (t_uint32)(asm_wrapper[i]) & 0x0000FFFF;
      idt[i].segment_selector = 8; // offset to kernel code segment in GDT.
      idt[i].unused = 0;
      idt[i].empty = 0;
      idt[i].size = 0b01110;
      idt[i].dpl = 0;
      idt[i].p = 1;
      idt[i].offset_high = ((t_uint32)(asm_wrapper[i]) & 0xFFFF0000) >> 16;
    }

}
